/**
 * Create by CaoWenjian
 *
 * @copyRight: 2018
 **/
package com.bjboot.caocao.system.service.impl;

import com.bjboot.caocao.common.utils.BuildTreeUtil;
import com.bjboot.caocao.system.dao.MenuDao;
import com.bjboot.caocao.system.dao.RoleMapper;
import com.bjboot.caocao.system.dao.RoleMenuMapper;
import com.bjboot.caocao.system.domain.MenuDO;
import com.bjboot.caocao.system.domain.Tree;
import com.bjboot.caocao.system.service.MenuService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 *@Description 菜单Service层实现类
 *@Author 操文健
 *@Date 2018-09-05 上午11:04
 *@Version 1.0
 **/
@Service
@Transactional(readOnly = true,rollbackFor = Exception.class)
public class MenuServiceImpl implements MenuService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private MenuDao menuMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    /**
     * 根据用户Id查询用户所有的菜单
     * @param id
     * @return
     */
    @Override
    public Tree<MenuDO> getSysMenuTree(Long id) {
        List<Tree<MenuDO>> trees = new ArrayList<Tree<MenuDO>>();
        List<MenuDO> menuDOs = menuMapper.listMenuByUserId(id);
        for (MenuDO sysMenuDO : menuDOs) {
            Tree<MenuDO> tree = new Tree<MenuDO>();
            tree.setId(sysMenuDO.getMenuId().toString());
            tree.setParentId(sysMenuDO.getParentId().toString());
            tree.setText(sysMenuDO.getName());
            Map<String, Object> attributes = new HashMap<>(16);
            attributes.put("url", sysMenuDO.getUrl());
            attributes.put("icon", sysMenuDO.getIcon());
            tree.setAttributes(attributes);
            trees.add(tree);
        }
        // 默认顶级菜单为０，根据数据库实际情况调整
        Tree<MenuDO> t = BuildTreeUtil.build(trees);
        return t;
    }

    /**
     * 查询所有的菜单信息
     * @param id
     * @return
     */
    @Override
    public List<Tree<MenuDO>> listMenuTree(Long id) {
        List<Tree<MenuDO>> treeList = new ArrayList<Tree<MenuDO>>();
        // 从数据库查询菜单信息
        List<MenuDO> menuDOList = menuMapper.listMenuByUserId(id);
        // 将每个菜单转换为一棵树
        for (MenuDO menuDO : menuDOList) {
            Tree<MenuDO> tree = new Tree<MenuDO>();
            tree.setId(menuDO.getMenuId().toString());
            tree.setParentId(menuDO.getParentId().toString());
            tree.setText(menuDO.getName());
            // 设置属性
            Map<String, Object> attributes = new HashMap<>(16);
            attributes.put("icon", menuDO.getIcon());
            attributes.put("url", menuDO.getUrl());
            tree.setAttributes(attributes);
            // 将每个tree添加到返回到前台界面中
            treeList.add(tree);
        }
        // 构建返回的系统树
        List<Tree<MenuDO>> returnTree = BuildTreeUtil.buildList(treeList, "0");
        return returnTree;
    }

    @Override
    public Tree<MenuDO> getTree() {
        List<Tree<MenuDO>> trees = new ArrayList<Tree<MenuDO>>();
        List<MenuDO> menuDOs = menuMapper.list(new HashMap<>(16));
        for (MenuDO sysMenuDO : menuDOs) {
            Tree<MenuDO> tree = new Tree<MenuDO>();
            tree.setId(sysMenuDO.getMenuId().toString());
            tree.setParentId(sysMenuDO.getParentId().toString());
            tree.setText(sysMenuDO.getName());
            trees.add(tree);
        }
        // 默认顶级菜单为０，根据数据库实际情况调整
        Tree<MenuDO> t = BuildTreeUtil.build(trees);
        return t;
    }

    /**
     * 根据RoleId查询权限
     * @param id
     * @return
     */
    @Override
    public Tree<MenuDO> getTree(Long id) {
        // 根据roleId查询权限
        List<MenuDO> menus = menuMapper.list(new HashMap<String, Object>(16));
        List<Long> menuIds = roleMenuMapper.listMenuIdByRoleId(id);
        List<Long> temp = menuIds;
        for (MenuDO menu : menus) {
            if (temp.contains(menu.getParentId())) {
                menuIds.remove(menu.getParentId());
            }
        }
        List<Tree<MenuDO>> trees = new ArrayList<Tree<MenuDO>>();
        List<MenuDO> menuDOs = menuMapper.list(new HashMap<String, Object>(16));
        for (MenuDO sysMenuDO : menuDOs) {
            Tree<MenuDO> tree = new Tree<MenuDO>();
            tree.setId(sysMenuDO.getMenuId().toString());
            tree.setParentId(sysMenuDO.getParentId().toString());
            tree.setText(sysMenuDO.getName());
            Map<String, Object> state = new HashMap<>(16);
            Long menuId = sysMenuDO.getMenuId();
            if (menuIds.contains(menuId)) {
                state.put("selected", true);
            } else {
                state.put("selected", false);
            }
            tree.setState(state);
            trees.add(tree);
        }
        // 默认顶级菜单为０，根据数据库实际情况调整
        Tree<MenuDO> t = BuildTreeUtil.build(trees);
        return t;
    }

    /**
     * 根据参数信息查询所有的菜单
     * @param params
     * @return
     */
    @Override
    public List<MenuDO> list(Map<String, Object> params) {
        List<MenuDO> menus = menuMapper.list(params);
        return menus;
    }

    /**
     * 根据菜单Id删除菜单
     * @param id
     * @return
     */
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    @Override
    public int remove(Long id) {
        int result = menuMapper.remove(id);
        return result;
    }

    /**
     * 新增菜单
     * @param menu
     * @return
     */
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    @Override
    public int save(MenuDO menu) {
        int r = menuMapper.save(menu);
        return r;
    }

    /**
     * 更新菜单
     * @param menu
     * @return
     */
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    @Override
    public int update(MenuDO menu) {
        int r = menuMapper.update(menu);
        return r;
    }

    /**
     * 查询菜单的明细信息
     * @param id
     * @return
     */
    @Override
    public MenuDO get(Long id) {
        MenuDO menuDO = menuMapper.get(id);
        return menuDO;
    }

    /**
     * 根据用户Id查询用户的所有的权限信息
     * @param userId
     * @return
     */
    @Override
    public Set<String> listPerms(Long userId) {
        List<String> perms = menuMapper.listUserPerms(userId);
        Set<String> permsSet = new HashSet<>();
        for (String perm : perms) {
            if (StringUtils.isNotBlank(perm)) {
                permsSet.addAll(Arrays.asList(perm.trim().split(",")));
            }
        }
        return permsSet;
    }
}
